using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace GameXNA_Master
{
    public interface InputService
    {

        event Action iExit;
        event Action iPause;
        event Action iSaveSettings;
        event Action<string> iLoad;
        event Action iStartNewLevel;

        void Save_Game_Settings();
        void Load_Game();
        void New_Game();
        void Exit_Game();
        void Pause_Game();
    }

    public class InputHandler : Microsoft.Xna.Framework.GameComponent, InputService
    {

        public event Action iExit;
        public event Action iPause;
        public event Action iSaveSettings;
        public event Action<string> iLoad;
        public event Action iStartNewLevel;
        Camera camera;
        
        


        MenuHandler screens_menu;
        RenderingData rendering_data;
        SettingsData settingsdata;

        KeyboardState kb;
        KeyboardState oldKb;

        GamePadState gp;
        GamePadState oldgp;

        
        public void Save_Game_Settings()
        {
            if (iSaveSettings != null)
                iSaveSettings();
        }

        public void Exit_Game()
        {
            if (iExit != null)
                iExit();

            Game.Exit();
        }

        public void New_Game()
        {
            if (iLoad != null)
                iLoad("NEW_GAME");
            Pause_Game();
        }

        public void Load_Game()
        {

            if (iLoad != null)
                iLoad("LOAD");
            Pause_Game();
        }

       public void Pause_Game()
       {
           if (iPause != null)
               iPause();
       }


        public InputHandler(Game game)
            : base(game)
        {
            game.Services.AddService(typeof(InputService), this);

        }

        protected override void Dispose(bool disposing)
        {
            Game.Services.RemoveService(typeof(InputService));
            base.Dispose(disposing);
        }
        
        public override void Initialize()
        {
            camera = (Camera)Game.Services.GetService(typeof(Camera));
            screens_menu = (MenuHandler)Game.Services.GetService(typeof(MenuHandler));
            rendering_data = (RenderingData)Game.Services.GetService(typeof(RenderingData));
            settingsdata = (SettingsData)Game.Services.GetService(typeof(SettingsData));

            iPause += () =>
            {
                Mouse.SetPosition(rendering_data.screenWidth / 2, rendering_data.screenHeight / 2);
            };

                     
            base.Initialize();
        }

        public override void Update(GameTime gameTime)
        {
            if (!gameInfoState.pause)
                settingsCamera(gameTime);

            
            if(settingsdata.useJoystic)         
                GamePadInput(gameTime);
            else
                KeyboardInput(gameTime);

            

            base.Update(gameTime);
        }

        private void settingsCamera(GameTime gameTime)
        {
            if (rendering_data == null)
                rendering_data = (RenderingData)Game.Services.GetService(typeof(RenderingData));


            camera.setCamera(rendering_data,settingsdata, (float)gameTime.ElapsedGameTime.TotalSeconds);

            BulletLogic.camera_rotation = camera.rotationY;
            BulletLogic.camera_sideMove = camera.sideMove;

        }


        private void GamePadInput(GameTime gameTime)
        {
            oldgp = gp;
            gp = GamePad.GetState(PlayerIndex.One);

            if (gp.IsConnected)
            {
                if (gp.Buttons.Y == ButtonState.Pressed && oldgp.Buttons.Y == ButtonState.Released) // tasto universale
                {
                    if (gameInfoState.pause_from_game)
                    {
                        if (iPause != null)
                            iPause();
                    }

                }

                if (!gameInfoState.pause)
                {

                    if (gp.Buttons.Back == ButtonState.Pressed && oldgp.Buttons.Back == ButtonState.Released) // select
                    {
                        (new SavegameHandler()).saveGame(BulletLogic.projectiles_enemies_State);
                        Console.WriteLine("GIOCO SALVATO");
                    }

                    if (gp.Buttons.Start == ButtonState.Pressed && oldgp.Buttons.Start == ButtonState.Released)
                    {
                        if (gameInfoState.Start_new_Level)
                        {
                            if (iStartNewLevel != null)

                                iStartNewLevel();
                        }
                        if (gameInfoState.game_over)
                        {
                            gameInfoState.game_over = false;
                            gameInfoState.pause_from_game = false;
                            if (iPause != null)

                                iPause();
                        }

                    }  


                }
                else
                {
                    if (gp.DPad.Up == ButtonState.Pressed && oldgp.DPad.Up == ButtonState.Released)
                        screens_menu.MoveSelectUp();
                    if (gp.DPad.Down == ButtonState.Pressed && oldgp.DPad.Down == ButtonState.Released)
                        screens_menu.MoveSelectDown();
                    if (gp.DPad.Left == ButtonState.Pressed && oldgp.DPad.Left == ButtonState.Released)
                        screens_menu.MoveSelectLeft();
                    if (gp.DPad.Right == ButtonState.Pressed && oldgp.DPad.Right == ButtonState.Released)
                        screens_menu.MoveSelectRight();
                    if (gp.Buttons.A == ButtonState.Pressed && oldgp.Buttons.A == ButtonState.Released)
                        screens_menu.Confirm();
                }
            }
            else
            {

                KeyboardInput(gameTime);                        

            }
        }


        private void KeyboardInput(GameTime gameTime)
        {
            oldKb = kb;
            kb = Keyboard.GetState();

            if (!gameInfoState.pause)
            {

                

                if (kb.IsKeyDown(Keys.F6) && oldKb.IsKeyUp(Keys.F6))
                {
                    (new SavegameHandler()).saveGame(BulletLogic.projectiles_enemies_State);
                    
                    Console.WriteLine("GIOCO SALVATO");
                }

                if (kb.IsKeyUp(Keys.Enter) && oldKb.IsKeyDown(Keys.Enter))
                {
                    if (gameInfoState.Start_new_Level)
                    {
                        if (iStartNewLevel != null)

                            iStartNewLevel();
                    }
                    if (gameInfoState.game_over)
                    {
                        gameInfoState.pause_from_game = false;
                        gameInfoState.game_over = false;
                        if (iPause != null)
                            iPause();
                    }

                } 


            }
            else
            {
                if (kb.IsKeyDown(Keys.W) && oldKb.IsKeyUp(Keys.W) || kb.IsKeyDown(Keys.Up) && oldKb.IsKeyUp(Keys.Up))
                    screens_menu.MoveSelectUp();
                if (kb.IsKeyDown(Keys.S) && oldKb.IsKeyUp(Keys.S) || kb.IsKeyDown(Keys.Down) && oldKb.IsKeyUp(Keys.Down))
                    screens_menu.MoveSelectDown();
                if ((kb.IsKeyDown(Keys.A) && oldKb.IsKeyUp(Keys.A) || kb.IsKeyDown(Keys.Left) && oldKb.IsKeyUp(Keys.Left)))
                    screens_menu.MoveSelectLeft();
                if ((kb.IsKeyDown(Keys.D) && oldKb.IsKeyUp(Keys.D) || kb.IsKeyDown(Keys.Right) && oldKb.IsKeyUp(Keys.Right)))
                    screens_menu.MoveSelectRight();
                if (kb.IsKeyUp(Keys.Enter) && oldKb.IsKeyDown(Keys.Enter))
                    screens_menu.Confirm();
            }


            /*Tasti universali*/
            if (kb.IsKeyDown(Keys.P) && oldKb.IsKeyUp(Keys.P) || kb.IsKeyDown(Keys.Escape) && oldKb.IsKeyUp(Keys.Escape))
            {
                if (gameInfoState.pause_from_game)
                {
                    if (iPause != null)
                        iPause();
                }

            }
        }




    }
}
